home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Supervisor's Toolkit
/
Network Supervisor's Toolkit.iso
/
tools
/
fn_ndi
/
ndir.prg
< prev
Wrap
Text File
|
1996-07-10
|
10KB
|
348 lines
/*
* File......: NDIR.PRG
* Author....: Mark Mitchelson
* CIS ID....: 76515,2207
* Date......: 9/20/94
* Revision..: $Revision$
* Log file..: $Logfile$
*
* This is an original work by Mark Mitchelson and placed in public domain.
*
*
* Modification history:
* ---------------------
*
* $Log$
*
*/
#include "fn_nDir.ch" // includes "Directory.ch"
#include "netto.ch"
//#define FT_TEST
#ifdef FT_TEST
FUNCTION main
LOCAL aDir, iOn, lNovell
// List all files in F:\SYSTEM
aDir := fn_nDir("F:\SYSTEM\*.*")
// Determine if using ndir() or directory() function
lNovell := ( Len(aDir) > 0 .and. Len(aDir) > F_ATTR )
// List results
? " File Size" + iif( lNovell, " Owner Create Date", "")
for iOn := 1 to Len( aDir )
? Padr( aDir[iOn][F_NAME], 18 ) ;
+ Str( aDir[iOn][F_SIZE], 12 ) + " " ;
+ Str( iif( lNovell, HILO2L(aDir[iOn][F_OWNER]), "" ), 12 ) + " " ;
+ iif( lNovell, Dtoc(aDir[iOn][F_CREATE]), "" )
next
?
RETURN nil
#endif
/* $DOC$
* $FUNCNAME$
* fn_nDir()
* $CATEGORY$
* File System
* $ONELINER$
* Mimics Directory() and includes Novell file attributes.
*
* $SYNTAX$
* fn_ndir( <cDirSpec> [, <cAttributes> ] ) --> <aDirectory>
*
* $ARGUMENTS$
* <cDirSpec> Drive with path to search for
* <cAttributes> Search for files with the file attributes.
* This is the convention used:
* R - Read Only
* H - Hidden
* S - System
* X - Execute only / Volume label
* D - Directory / Subdirectory bit
* A - Archive
* F - Shareable file
*
* $RETURNS$
* <aDirectory> - Empty if nothing found or no rights to that location.
*
* { { F_NAME, F_SIZE, F_DATE, F_TIME, F_ATTRIB,
* F_OWNER, F_CREATE, F_LASTACCESS }, ... }
*
* F_DATE is the last update date
* F_TIME is the last update time
*
* F_ATTRIB -> "Sh" sharable
* "Sy" system
* "Ro" readonly
* [REST FOLLOW THE VALUS FOR <cAttributes>]
*
* NOTE: F_OWNER, F_CREATE, F_LASTACCESS are only entered when the
* directory is Novell's.
*
* $DESCRIPTION$
* This function mimics the Clipper function Directory(). On a
* Novell drive it will include the owner #, creation date and the
* last access date.
*
* The user must have rights to the directory to view it on Novell.
*
* $EXAMPLES$
* fn_ndir("F:\PUBLIC\*.EXE") => { ... }
* fn_ndir("*.*", "AH") => { ... }
*
* $SEEALSO$
*
* $INCLUDE$
* fn_nDir.ch required if you want the return array indexes named,
* i.e. F_NAME, F_OWNER
*
* $END$
*/
FUNCTION fn_ndir( cDirList, cDirAttrib )
// Get the drive letter from the directory. (first two characters)
LOCAL aDirectory := {}
LOCAL cRequest
LOCAL cReply
LOCAL cFileSpec, nAttrSpec
LOCAL nFileAttrib, cSeq
LOCAL nDrvHandle, nTemp, cTemp
// Set default values
cDirList := Upper( cDirList )
DEFAULT cDirAttrib TO ""
// Determine if Novell or Other Drive
if At( ":", cDirList ) = 0
// No drive included
nDrvHandle := fn_getdh( fn_DriveNum( ft_Default()))
else
nDrvHandle := fn_getdh( fn_DriveNum( cDirList ))
endif
if nDrvHandle > 0
// Novell Network Directory
//--------------------------
// Define <cFileSpec>
if At( ":", cDirList ) = 0
// i.e. public\*.*, *.*
cFileSpec := fn_DVolName( ft_Default() ) + ":\" ;
+ iif( Empty(cDirList), "*.*", cDirList )
else
// i.e. f:\public, f:*.*
cFileSpec := fn_DVolName( Left(cDirList,1)) + ":"
cDirList := Substr( cDirList, At( ":", cDirList )+1 )
cFileSpec += iif( Left( cDirList, 1 ) = "\", "", "\") + cDirList
endif
// Define <nAttrSpec>
nAttrSpec := 0
iif( cDirAttrib $ "R", nAttrSpec := fn_setbit( nAttrSpec, 0 ), )
iif( cDirAttrib $ "H", nAttrSpec := fn_setbit( nAttrSpec, 1 ), )
iif( cDirAttrib $ "S", nAttrSpec := fn_setbit( nAttrSpec, 2 ), )
iif( cDirAttrib $ "X", nAttrSpec := fn_setbit( nAttrSpec, 3 ), )
iif( cDirAttrib $ "D", nAttrSpec := fn_setbit( nAttrSpec, 4 ), )
iif( cDirAttrib $ "A", nAttrSpec := fn_setbit( nAttrSpec, 5 ), )
iif( cDirAttrib $ "F", nAttrSpec := fn_setbit( nAttrSpec, 7 ), ) // "Sh"
// Loop through all in directory
//-------------------------------
cSeq := I2Bin( -1 ) // Start up the search
do while .T.
// Build Request
cRequest := I2BYTE( 15 ) ; // Subservice 0Fh
+ cSeq ; // FFFFh - start sequence
+ I2BYTE( 0 ) ; // Dir handle (OPTIONAL)
+ I2BYTE( nAttrSpec ) ; // Novell search attrib bits
+ I2BYTE( Len(cFileSpec)) ;// Len of file spec
+ Upper(cFileSpec)
cReply := Replicate( chr(0), 94 )
// Transaction
if _fnReq( 227, cRequest, @cReply ) == ESUCCESS // E3h
// Process Reply
//---------------
aadd( aDirectory, Array( 8 ))
cSeq := Substr( cReply, 0, 2 )
aTail(aDirectory)[F_NAME] := fn_NoNull( Substr( cReply, 3, 14 ))
nTemp := Asc( Substr( cReply, 17, 1 ))
aTail(aDirectory)[F_ATTR] := iif( fn_isbit(nTemp,0), "Ro", "") ; // ReadOnly
+ iif( fn_isbit(nTemp,1), "H", "") ; // Hidden
+ iif( fn_isbit(nTemp,2), "Sy", ""); // System
+ iif( fn_isbit(nTemp,3), "X", "") ; // Execute-Only
+ iif( fn_isbit(nTemp,4), "D", "") ; // Directory
+ iif( fn_isbit(nTemp,5), "A", "") ; // Archive
+ iif( fn_isbit(nTemp,7), "Sh", "") // Share
aTail(aDirectory)[F_SIZE] := HILO2L( Substr( cReply, 19, 4 )) // Size
aTail(aDirectory)[F_DATE] := fn_W2Date( Substr( cReply, 27, 2 )) // Last Change Date
aTail(aDirectory)[F_TIME] := fn_W2Time( Substr( cReply, 29, 2 )) // Last Change Time
aTail(aDirectory)[F_OWNER] := Id2Owner( Substr( cReply, 31, 4 )) // Owner
* aTail(aDirectory)[F_CREATE] := fn_W2Date( Substr( cReply, 23, 2 )) // Create
* aTail(aDirectory)[F_LASTACCESS] := fn_W2Date( Substr( cReply, 25, 2 )) // Last Access
else
EXIT
endif
enddo
else
// LOCAL or Non Novell Drive
aDirectory := Directory( cDirList, cDirAttrib )
endif
RETURN(aDirectory)
/* $DOC$
* $FUNCNAME$
* fn_DriveNum()
* $CATEGORY$
* Miscellanious
*
* $ONELINER$
* Convert a drive letter to its DOS numeric
*
* $SYNTAX$
* fn_ndir( [<cDrive> | <cDriveWithPath> ] ) -> integer
*
* $ARGUMENTS$
*
* $RETURNS$
* Array
*
* $DESCRIPTION$
*
* $EXAMPLES$
* fn_DriveNum("C") -> 3
* fn_DriveNum("F:\PUBLIC") -> 5
*
* $SEEALSO$
*
* $INCLUDE$
* netto.ch
* $END$
*/
FUNCTION fn_DriveNum( cDrive )
// Convert a drive letter to its number A=0,..F=5,...
RETURN( Asc(Upper(Left(cDrive,1))) - Asc('A') )
/* $DOC$
* $FUNCNAME$
* fn_W2Date()
* $CATEGORY$
* Miscellanious
* $ONELINER$
* Convert a dos binary date to its Clipper equivalant.
*
* $SYNTAX$
* fn_W2Date( <cWord> ) -> date
*
* $ARGUMENTS$
*
* $RETURNS$
* Date, Invalid date on error
*
* $DESCRIPTION$
* This converts a 2 character representation of a binary word to a
* Clipper date.
*
* Byte1 Byte 2
* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
* | Year | Month | Day |
*
*
* $EXAMPLES$
*
* $SEEALSO$
*
* $INCLUDE$
* netto.ch
* $END$
*/
FUNCTION fn_W2Date( cWord )
// Convert the 2 byte word to a data
LOCAL nYear, nMonth, nDay, cTemp
// Bytes 15-9
cTemp := fn_ror( " "+Left( cWord, 1 ), 1 )
nYear := 80 + Asc( Substr( cTemp, 2, 1 ))
// Bytes 8-5
cTemp := fn_ror( cWord, 5 )
nMonth := fn_And( Asc( Substr( cTemp, 2, 1 )), 15 )
// Bytes 4-0
nDay := fn_And( Asc( Substr( cWord, 2, 1 )), 31 )
RETURN( Ctod( Str(nMonth,2)+"/"+Str(nDay,2)+"/"+Str(nYear,2) ))
/* $DOC$
* $FUNCNAME$
* fn_W2Time()
* $CATEGORY$
* Miscellanious
* $ONELINER$
* Convert a dos binary time to its Clipper equivalant.
*
* $SYNTAX$
* fn_W2Time( <cWord> ) -> time
*
* $ARGUMENTS$
*
* $RETURNS$
* Time - "XX:XX:XX"
*
* $DESCRIPTION$
* This converts a 2 character representation of a binary word to a
* Clipper time.
*
* Byte1 Byte 2
* 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
* | Time | Minute | Second |
*
*
* $EXAMPLES$
*
* $SEEALSO$
*
* $INCLUDE$
* netto.ch
* $END$
*/
FUNCTION fn_W2Time( cWord )
// Convert the 2 byte word to a time
LOCAL cTemp
LOCAL nHour, nMin, nSec
// Bytes 15-11
cTemp := fn_ror( " "+Left( cWord, 1 ), 3 )
nHour := Asc( Substr( cTemp, 2, 1 ))
// Bytes 10-5
cTemp := fn_ror( cWord, 5 )
nMin := fn_And( Asc( Substr( cTemp, 2, 1 )), 63 )
// Bytes 4-0
nSec := fn_And( Asc( Substr( cWord, 1, 2 )), 31 )
RETURN( lTrim(Str(nHour))+":"+lTrim(Str(nMIn))+":"+lTrim(Str(nSec)) )
STATIC FUNCTION Id2Owner( cDWord )
// Convert a Double Word Owner ID to a name
LOCAL cTemp, nType := OT_USER
cTemp := FN_BndONam( HILO2L(cDWord), @nType )
RETURN( cTemp )
// end